package ar.edu.unicen.exa.isistan.archassis.ia.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ar.edu.unicen.exa.isistan.archassis.DiffRequestData;
import ar.edu.unicen.exa.isistan.archassis.ia.api.EvalResult;
import ar.edu.unicen.exa.isistan.archassis.ia.api.IAIModule;
import ar.edu.unicen.exa.isistan.archassis.ia.api.ItemCaseEvalResult;
import ar.edu.unicen.exa.isistan.archassis.ia.api.JavaClassEvalResult;
import ar.edu.unicen.exa.isistan.archassis.ia.api.ListCasesEvalResult;
import ar.edu.unicen.exa.isistan.archassis.ia.api.db.ItemCase;
import ar.edu.unicen.exa.isistan.archassis.ia.api.db.JavaClass;
import ar.edu.unicen.exa.isistan.archassis.ia.api.db.ListCases;

public class AISeedModule implements IAIModule {
	
	private Map<Long,ListCases> lc = null;
	

	public void addItemCase(Long id, ItemCase la) throws Exception {
		if (lc == null) {
			loadLC();
		}
		//Se calcula el nuevo peso del sistema
		ListCases listC = lc.get(id);
		if (listC != null){
			listC.addCase(la);
		}else{
			throw new Exception("El ID del caso no existe");
		}
		saveLC();

	}
	
	@Override
	public Map<Long,ListCases> getAllCases() {
		if (lc == null) {
			loadLC();
		}
		return lc;
	}
	
	@Override
	public void addListCases(ListCases listCases) {
		listCases.setId(getNextId());
		lc.put(listCases.getId(), listCases);
		saveLC();
		
	}
	
	private Long getNextId(){
		if (lc == null) {
			loadLC();
		}
		return new Long(lc.size()+1);
	}
	
	public Long getCurrentId(){
		if (lc == null) {
			loadLC();
		}
		return new Long(lc.size());
	}


	private void saveLC() {
		File donde = new File(DiffRequestData.tempDir(), "aidata.dat");
		
		if (lc == null) {
			lc = new HashMap<Long,ListCases>();
		}
		
		try {
			ObjectOutputStream fileOut = new ObjectOutputStream(new FileOutputStream(donde));
			fileOut.writeObject(lc);
			fileOut.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
	

	@SuppressWarnings("unchecked")
	private void loadLC() {
		File donde = new File(DiffRequestData.tempDir(), "aidata.dat");
		try {

			ObjectInputStream fileIn = new ObjectInputStream(new FileInputStream(donde));
			lc = (Map<Long,ListCases>)fileIn.readObject();
			fileIn.close();
		} catch (Exception e) {
			System.err.println(e.getMessage());
			// TODO: handle exception
			//e.printStackTrace();
		}
		if (lc == null) {
			lc = new HashMap<Long,ListCases>();
		}
		
	}

	@Override
	public EvalResult evaluate(List<JavaClass> javaClassList) {
		if (lc == null) {
			loadLC();
		}
		EvalResult evalResult = new EvalResult();
		long currentTimeInMilis = System.currentTimeMillis();
		for (ListCases listCasesBean : lc.values()) {
			ListCasesEvalResult listCasesEvalResult = new ListCasesEvalResult(listCasesBean);
			for (ItemCase itemCase : listCasesBean.getCases()) {
				ItemCaseEvalResult itemCaseEvalResult = new ItemCaseEvalResult(listCasesEvalResult, itemCase);
				for (JavaClass javaClass : itemCase.getComponents()) {
					for (JavaClass inputJavaClass : javaClassList) {
						JavaClassEvalResult javaClassEvalResult = evalResult.getJavaClassEvalResult(inputJavaClass);
						javaClassEvalResult.eval(javaClass, itemCase, listCasesBean);
						
						itemCaseEvalResult.add(javaClass, inputJavaClass);
					}
				}
				listCasesEvalResult.set(itemCaseEvalResult);
			}
			evalResult.add(listCasesEvalResult);
		}
		evalResult.getSummaryAmountData().setCasesCount(lc.size());
		evalResult.getSummaryAmountData().setTimeElapsed(System.currentTimeMillis() - currentTimeInMilis);
		evalResult.getSummaryAmountData().setJavaClassCount(javaClassList.size());
		return evalResult;
	}
	
//	private static ListCasesResult process(ListCases caseSeedList, List<JavaClass> javaClassList) {
//		ListCasesResult result = new ListCasesResult(caseSeedList, javaClassList);
//		return result;
//	}
/*
	public float getMaxPesoClass() {
		if(maxPesoClass == 0){
			for (String name : lc.keySet()) {
				for (JavaClass lci : lc.get(name)) {
					if (lci.getPeso() > maxPesoClass){
						maxPesoClass = lci.getPeso();
					}
				}
			}
		}
		return maxPesoClass;
	}
	
	public static float getMaxPesoSeed() {
		if(maxPesoSeed == 0){
			for (String name : lc.keySet()) {
				for (JavaClass lci : lc.get(name)) {
					if (lci.getMaxPesoSemilla() > maxPesoSeed){
						maxPesoSeed = lci.getMaxPesoSemilla();
					}
				}
			}
		}
		return maxPesoSeed;
	}
*/
	
	

}
